using System;

namespace HEFramework
{
    /// <summary>
    /// 实体继承接口表示实体需要初始化，不做任何特殊处理
    /// </summary>
    public interface IAwake
    {
    }

    public interface IAwake<A>
    {
    }

    public interface IAwake<A, B>
    {
    }

    public interface IAwake<A, B, C>
    {
    }

    public interface IAwake<A, B, C, D>
    {
    }

    public interface IAwakeSystem : ISystemType
    {
        void Run(Entity _o);
    }

    public interface IAwakeSystem<A> : ISystemType
    {
        void Run(Entity _o, A _a);
    }

    public interface IAwakeSystem<A, B> : ISystemType
    {
        void Run(Entity _o, A _a, B _b);
    }

    public interface IAwakeSystem<A, B, C> : ISystemType
    {
        void Run(Entity _o, A _a, B _b, C _c);
    }

    public interface IAwakeSystem<A, B, C, D> : ISystemType
    {
        void Run(Entity _o, A _a, B _b, C _c, D _d);
    }

    [EntitySystem]
    public abstract class AwakeSystem<T> : IAwakeSystem where T : Entity, IAwake
    {
        Type ISystemType.Type()
        {
            return typeof(T);
        }

        Type ISystemType.SystemType()
        {
            return typeof(IAwakeSystem);
        }

        int ISystemType.GetInstanceQueueIndex()
        {
            return InstanceQueueIndex.None;
        }

        void IAwakeSystem.Run(Entity _o)
        {
            this.Awake((T)_o);
        }

        protected abstract void Awake(T _self);
    }

    [EntitySystem]
    public abstract class AwakeSystem<T, A> : IAwakeSystem<A> where T : Entity, IAwake<A>
    {
        Type ISystemType.Type()
        {
            return typeof(T);
        }

        Type ISystemType.SystemType()
        {
            return typeof(IAwakeSystem<A>);
        }

        int ISystemType.GetInstanceQueueIndex()
        {
            return InstanceQueueIndex.None;
        }

        void IAwakeSystem<A>.Run(Entity _o, A _a)
        {
            this.Awake((T)_o, _a);
        }

        protected abstract void Awake(T _self, A _a);
    }

    [EntitySystem]
    public abstract class AwakeSystem<T, A, B> : IAwakeSystem<A, B> where T : Entity, IAwake<A, B>
    {
        Type ISystemType.Type()
        {
            return typeof(T);
        }

        Type ISystemType.SystemType()
        {
            return typeof(IAwakeSystem<A, B>);
        }

        int ISystemType.GetInstanceQueueIndex()
        {
            return InstanceQueueIndex.None;
        }

        void IAwakeSystem<A, B>.Run(Entity _o, A _a, B _b)
        {
            this.Awake((T)_o, _a, _b);
        }

        protected abstract void Awake(T _self, A _a, B _b);
    }

    [EntitySystem]
    public abstract class AwakeSystem<T, A, B, C> : IAwakeSystem<A, B, C> where T : Entity, IAwake<A, B, C>
    {
        Type ISystemType.Type()
        {
            return typeof(T);
        }

        Type ISystemType.SystemType()
        {
            return typeof(IAwakeSystem<A, B, C>);
        }

        int ISystemType.GetInstanceQueueIndex()
        {
            return InstanceQueueIndex.None;
        }

        void IAwakeSystem<A, B, C>.Run(Entity _o, A _a, B _b, C _c)
        {
            this.Awake((T)_o, _a, _b, _c);
        }

        protected abstract void Awake(T _self, A _a, B _b, C _c);
    }

    [EntitySystem]
    public abstract class AwakeSystem<T, A, B, C, D> : IAwakeSystem<A, B, C, D> where T : Entity, IAwake<A, B, C, D>
    {
        Type ISystemType.Type()
        {
            return typeof(T);
        }

        Type ISystemType.SystemType()
        {
            return typeof(IAwakeSystem<A, B, C, D>);
        }

        int ISystemType.GetInstanceQueueIndex()
        {
            return InstanceQueueIndex.None;
        }

        void IAwakeSystem<A, B, C, D>.Run(Entity _o, A _a, B _b, C _c, D _d)
        {
            this.Awake((T)_o, _a, _b, _c, _d);
        }

        protected abstract void Awake(T _self, A _a, B _b, C _c, D _d);
    }
}